home *** CD-ROM | disk | FTP | other *** search
- /*$Author: DCODY $*/
- /*$Date: 28 Jul 1992 14:28:32 $*/
- /*$Header: W:/sccs/pcmapps/waveit.c_v 1.2 28 Jul 1992 14:28:32 DCODY $*/
- /*$Log: W:/sccs/pcmapps/waveit.c_v $
- *
- * Rev 1.2 28 Jul 1992 14:28:32 DCODY
- * added parameter for 16 pcm specified on the command line.
- *
- * Rev 1.1 23 Jun 1992 16:10:28 DCODY
- * No change.
- *
- * Rev 1.0 15 Jun 1992 09:26:58 BCRANE
- * Initial revision.
- */
- /*$Logfile: W:/sccs/pcmapps/waveit.c_v $*/
- /*$Modtimes$*/
- /*$Revision: 1.2 $*/
- /*$Workfile: waveit.c $*/
-
-
- /*\
- |*|----====< WaveIt.C >====----
- |*|
- |*| Convert a ".VOC" file to a Wave file
- |*|
- |*| Copyright (c) 1991, Media Vision, Inc. All rights reserved.
- |*|
- \*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <malloc.h>
-
- #include "play.h"
- #include "common.h"
-
-
- /*\
- |*|----====< Local Variables >====----
- \*/
-
- static FILE *inf; /* ".VOC" input file */
- static FILE *ouf; /* ".WAV" output file */
-
- VOCHDR VOCHeader; /* block header */
- bVOCDATA b1VoiceData; /* voice daa header */
- bCONTINUE b2VoiceData; /* continuation block header */
-
- WaveInfo _WaveHeader = { /* Wave File Header */
- 1, /* format category */
- 1, /* stereo/mono */
- 0, /* sample rate */
- 0, /* stereo * sample rate */
- 1, /* block alignment (1=byte) */
- 8 /* # byte bits per sample */
- };
-
- int SampleRate; /* Sample data rate */
- long SampleSize; /* # of bytes in the sample */
- long TotalSampleSize = 0; /* total length of sample data */
-
- long UserSampleRate = -1; /* default to prompt operator */
- int UserStereoMono = 0; /* default to mono */
- int PCMSize = 8;
-
- char SourceFile[100]; /* source file name storage */
- char TargetFile[100]; /* target file name storage */
- int lastsample; /* last valid pcm sample */
-
- static fpos_t riffpos;
- static fpos_t datapos;
-
- int PadByte;
- int BlockType;
-
- int FileType;
-
- long GetPlayRate();
- char getkey();
-
- #define VOC_FORMAT 0x0001
- #define SOU_FORMAT 0x0002
-
-
- /*\
- |*|
- |*|----====< Main >====----
- |*|
- |*| Play the voice file out to the PCM hardware
- |*|
- \*/
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
-
- /* set the runtime switches */
-
- CommandLine (argc,argv);
-
- /* get header data from the .VOC file & point to the first block */
-
- PreProcessFile ();
-
- /* output the wave file data... */
-
- lastsample = GetNextSample();
- while (!feof (inf)) {
- putc (lastsample,ouf);
- lastsample = GetNextSample();
- TotalSampleSize++;
- }
-
- WriteckSize ( );
- fclose ( ouf );
-
- /* exit to DOS */
-
- DoExit(0);
-
- }
-
- /*\
- |*|----====< CommandLine >====----
- |*|
- |*| process the command line switches
- |*|
- \*/
- int CommandLine(argc,argv)
- int argc;
- char *argv[];
- {
- char *s,c;
- int n,temp;
- long longtemp;
-
- /* logo... */
-
- printf ("\nPCM Conversion Utility, version 1.05\n");
- printf ("Courtesy of Media Vision, Inc., Fremont, CA.\n\n");
-
- /* exit if too few parameters */
-
- if (argc < 3) {
-
- printf (" To Use: DOS>WAVEIT [FILE.xxx] [FILE.WAV] [Rxxxx] [s] [16]\n\n");
- printf (" Where: [FILE.xxx] is a .VOC or other 8 bit PCM input file.\n");
- printf (" [FILE.WAV] is the .WAV output file.\n");
- printf (" [Rxxxxx] specifies a new sample rate.\n");
- printf (" [S] specifies stereo instead of mono.\n");
- printf (" [16] specifies 16 bit PCM\n\n");
- DoExit (1);
- }
-
- /* attempt to open the users disk file */
-
- strcpy (SourceFile,argv[1]);
- if ((inf = fopen(argv[1],"rb")) == 0) {
- printf ("\aBad Input File Name: \"%s\" Try Again!\n",argv[1]);
- DoExit (1);
- }
-
- /* make sure the new target does not exist */
-
- if ((ouf = fopen(argv[2],"rb")) != 0) {
- fclose (ouf);
- printf ("\"%s\" already exists. Overwrite? (y/n) ",argv[2]);
- c = getkey();
- if ((c & 0x5f) != 'Y')
- DoExit (1);
- }
-
- /* attempt to open our work file */
-
- strcpy (TargetFile,argv[2]);
- if ((ouf = fopen(argv[2],"wb")) == 0) {
- printf ("\Bad Output File Name: \"%s\" Try Again!\n");
- DoExit (1);
- }
-
- /* determine if this is a .sou (or any non-.voc file file */
-
- s = argv[1] - 1;
- while (*++s) {
- if (islower(*s))
- *s &= 0x5f;
- }
-
- if (strcmp (s-4,".VOC") == 0)
- FileType = VOC_FORMAT;
- else
- FileType = SOU_FORMAT;
-
- /* process the other command line switches */
-
- n = 3;
- while (n < argc) {
-
- s = argv[n++];
-
- if (*s == '/') s++;
- if (*s == '-') s++;
-
- switch (*s & 0x5f) {
-
- case '1' & 0x5f:
- PCMSize = 16;
- break;
-
- case 'R':
- if (sscanf (++s,"%ld",&longtemp) == 1) {
- if ((longtemp >4000L) && (longtemp < 88200L))
- UserSampleRate = longtemp;
- }
- break;
-
- case 'S':
- UserStereoMono = 1;
- break;
-
- default:
- break;
- }
- }
-
- }
-
-
- /*\
- |*|----====< DoExit() >====----
- |*|
- |*| Exit to DOS
- |*|
- \*/
- int DoExit(cc)
- int cc;
- {
- fclose (ouf);
- exit (cc);
- }
-
- /*\
- |*|----====< GetNextSample >====----
- |*|
- |*| Get the next sample byte
- |*|
- \*/
- int GetNextSample()
- {
- char buff[10],*b;
- long *ptr;
- int n;
-
- if (FileType == SOU_FORMAT) {
- return (getc(inf));
- }
- else {
-
- /* if data available, just return the next byte */
-
- if (SampleSize--) {
-
- switch (BlockType) {
-
- case VOICECONTINUE:
- case VOICEDATA:
- return (getc(inf));
-
- case SILENCE:
- default:
- return (0x80);
- }
- }
-
- /* process each voice data record */
- /* get the next partial header */
-
- b = (char *) &b1VoiceData;
- for (n=0;n<(sizeof(bVOCDATAHDR));n++)
- *b++ = getc(inf);
-
- /* process the header */
-
- switch (BlockType = (b1VoiceData.btype & 0xff) ) {
-
- case TERMINATOR:
-
- /* all done, just quit now. who cares... */
-
- WriteckSize();
- DoExit(0);
-
- case VOICECONTINUE:
-
- /* get the size of the data portion */
-
- ptr = (long*) &b1VoiceData.bsize[0];
- SampleSize = (*ptr & 0x00ffffff);
-
- /* return the next byte */
-
- SampleSize--;
- return (getc(inf));
-
- case VOICEDATA:
-
- /* fill out the rest of the header */
-
- for (n=0;n<(sizeof(bVOCDATA)-(sizeof(bVOCDATAHDR)));n++)
- *b++ = getc(inf);
-
- /* get the size of the data portion */
-
- ptr = (long*) &b1VoiceData.bsize[0];
- SampleSize = (*ptr & 0x00ffffff) - 2;
-
- /* return the next byte */
-
- SampleSize--;
- return (getc(inf));
-
- case SILENCE:
-
- /* fill out the rest of the header */
-
- for (n=0;n<(sizeof(bSILENCE)-(sizeof(bVOCDATAHDR)));n++)
- *b++ = getc(inf);
-
- SampleSize = LONG (((bSILENCE*)&b1VoiceData)->period);
-
- SampleSize--;
- return (0x80);
-
- case MARKER:
- printf ("MARKER - Currently an Unsupported header entry!\n");
- DoExit(0);
-
- case ASCIITEXT:
- printf ("ASCIITEXT - Currently an Unsupported header entry!\n");
- DoExit(0);
-
- case REPEAT:
- printf ("REPEAT - Currently an Unsupported header entry!\n");
- DoExit(0);
-
- case ENDREPEAT:
- printf ("ENDREPEAT - Currently an Unsupported header entry!\n");
- DoExit(0);
-
- default:
- printf ("\aUnknown record type encountered in .VOC file!\n");
- DoExit(0);
- }
- }
- }
-
-
- /*\
- |*|----====< getkey >====----
- |*|
- |*| get a key
- |*|
- \*/
- char getkey()
- {
- char c;
-
- while (kbhit()) getch();
- while (!kbhit()) ;
- putch(c = getch());
- putch('\n');
- putch('\r');
- return (c);
- }
-
-
- /*\
- |*|----====< GetPlayRate >====----
- |*|
- |*| Get the playing rate of this sample.
- |*|
- \*/
- long GetPlayRate(ptr)
- bVOCDATA *ptr;
- {
- int n;
- char c;
- char buff[100];
-
- switch (FileType) {
-
- case VOC_FORMAT:
-
- /* get the sample rate */
-
- if (UserSampleRate != -1)
- return(UserSampleRate);
-
- n = ptr->sampler & 0xff;
-
- while (1) {
- if (n == 166)
- return (11025L);
-
- if (n == 211)
- return (22050L);
-
- printf ("\n.WAV files only accept 11k or 22k from .VOC files. Your .VOC file\n");
- printf ("indicates this sample to be recorded at %ldkhz. Do you wish to\n",(1000000L/(256-n)));
- printf ("(A)accept this, or make it (1)11k, (2)22k, (O)other or (Q)quit (A/1/2/O/Q) ");
-
- c = getkey();
-
- switch (c) {
-
- case 'a':
- case 'A':
- return ( LONG(1000000L/(256-n)) );
-
- case '1':
- return (11025L);
- break;
-
- case '2':
- return (22050L);
- break;
-
- case 'O':
- case 'o':
- do {
- printf ("Enter the new sample rate :");
- gets(buff);
- } while (sscanf (buff,"%ld",&UserSampleRate) != 1);
- return (UserSampleRate);
-
- case 'Q':
- case 'q':
- DoExit();
-
- default:;
- }
- }
- break;
-
- case SOU_FORMAT:
-
- /* need a sample rate */
-
- if (UserSampleRate != -1)
- return(UserSampleRate);
-
- printf ("The .SOU file needs a sample rate.\n");
- printf ("Do you wish to make it (1)11k, (2)22k or (o)other? (1/2/O) ");
-
- c = getkey();
-
- switch (c) {
-
- case 'O':
- case 'o':
- do {
- printf ("Enter the new sample rate :");
- gets(buff);
- } while (sscanf (buff,"%ld",&UserSampleRate) != 1);
- return (UserSampleRate);
-
- case '1':
- return (11025L);
-
- case '2':
- return (22050L);
-
- default:;
- }
-
- default:
- break;
-
- }
-
- }
-
-
- /*\
- |*|----====< PreProcessFile >====----
- |*|
- |*| Get the header data & return pointing to the 1st byte in the file
- |*|
- \*/
- int PreProcessFile()
- {
- long *ptr;
- int n;
- char *b,c;
-
-
- if (FileType == VOC_FORMAT) {
-
- /* rewind the input file to the 1st byte */
-
- fseek(inf,0L,SEEK_SET);
-
- /* get the header of the voice file */
-
- b = (char *) &VOCHeader;
- for (n=0;n<(sizeof (VOCHDR));n++)
- *b++ = getc(inf);
-
- if (feof(inf)) {
- printf ("\aUnexpected EOF on input from Voice File\n");
- DoExit (1);
- }
-
- /* Make sure it's a legit file */
-
- if (strncmp (VOCHeader.id,"Creative Voice File",0x13) != 0) {
- printf ("\aInvalid Header in Voice File\n");
- DoExit (1);
- }
-
- /* process the 1st voice data record */
- /* bomb out if eof */
-
- if (feof(inf)) {
- printf ("\aUnexpected EOF on input!\n");
- DoExit(0);
- }
-
- /* get the next partial header */
-
- b = (char *) &b1VoiceData;
- for (n=0;n<(sizeof(bVOCDATAHDR));n++)
- *b++ = getc(inf);
-
- /* process the header */
-
- switch (BlockType = (b1VoiceData.btype & 0xff) ) {
-
- case VOICEDATA:
-
- /* fill out the rest of the header */
-
- for (n=0;n<(sizeof(bVOCDATA)-(sizeof(bVOCDATAHDR)));n++)
- *b++ = getc(inf);
-
- _WaveHeader.nSamplesPerSec =
- GetPlayRate(&b1VoiceData);
- _WaveHeader.nAvgBytesPerSec =
- _WaveHeader.nSamplesPerSec<<UserStereoMono;
-
- _WaveHeader.nChannels = UserStereoMono+1;
- _WaveHeader.nBlockAlign = UserStereoMono+1;
-
- /* get the size of the data portion */
-
- ptr = (long*) &b1VoiceData.bsize[0];
- SampleSize = (*ptr & 0x00ffffff) - 2;
- break;
-
- case TERMINATOR:
- printf ("Terminator encountered - No sample data in the file!\n");
- DoExit(0);
-
- case VOICECONTINUE:
- printf ("VOICECONTINUE - Not supported as the 1st record\n");
- DoExit(0);
-
- case SILENCE:
-
- /* fill out the rest of the header */
-
- for (n=0;n<(sizeof(bSILENCE)-(sizeof(bVOCDATAHDR)));n++)
- *b++ = getc(inf);
-
- SampleSize = LONG (((bSILENCE*)&b1VoiceData)->period);
- break;
-
- case MARKER:
- printf ("MARKER - Currently an Unsupported header entry!\n");
- DoExit(0);
-
- case ASCIITEXT:
- printf ("ASCIITEXT - Currently an Unsupported header entry!\n");
- DoExit(0);
-
- case REPEAT:
- printf ("REPEAT - Currently an Unsupported header entry!\n");
- DoExit(0);
-
- case ENDREPEAT:
- printf ("ENDREPEAT - Currently an Unsupported header entry!\n");
- DoExit(0);
-
- default:
- printf ("\aUnknown record type encountered in .VOC file!\n");
- DoExit(0);
- }
- }
-
- if (FileType == SOU_FORMAT) {
-
- if (UserSampleRate != -1)
- c = UserStereoMono;
- else {
- while (1) {
- printf ("\nEnter (1) for mono, (2) for stereo: ");
- c = getkey();
- c -= 0x31;
- if (!((c < 0) || (c > 1)))
- break;
- }
- UserStereoMono = c;
- }
-
- _WaveHeader.nSamplesPerSec =
- GetPlayRate(&b1VoiceData);
- _WaveHeader.nAvgBytesPerSec =
- _WaveHeader.nSamplesPerSec << UserStereoMono;
-
- _WaveHeader.nChannels = UserStereoMono+1;
- _WaveHeader.nBlockAlign = UserStereoMono+1;
- }
-
- /* with the new header data, write it out to the new file */
-
- putc ('R',ouf); /* riff header */
- putc ('I',ouf);
- putc ('F',ouf);
- putc ('F',ouf);
-
- fgetpos (ouf,&riffpos);
-
- putc (0x00,ouf); /* riff length */
- putc (0x00,ouf);
- putc (0x00,ouf);
- putc (0x00,ouf);
-
- putc ('W',ouf); /* wave header */
- putc ('A',ouf);
- putc ('V',ouf);
- putc ('E',ouf);
-
- putc ('f',ouf); /* wave fmt block */
- putc ('m',ouf);
- putc ('t',ouf);
- putc (' ',ouf);
-
- putc (0x10,ouf); /* wave fmt block length */
- putc (0x00,ouf);
- putc (0x00,ouf);
- putc (0x00,ouf);
-
- /* handle 16 bit PCM changes to the header */
-
- _WaveHeader.nBitsPerSample = PCMSize;
- if (PCMSize == 16)
- _WaveHeader.nAvgBytesPerSec <<= 1;
-
- b = (char *) &_WaveHeader; /* wave data structure */
-
- for (n=0;n<(sizeof(WaveInfo));n++)
- putc (*b++,ouf);
-
- putc ('d',ouf); /* data header */
- putc ('a',ouf);
- putc ('t',ouf);
- putc ('a',ouf);
-
- fgetpos (ouf,&datapos);
-
- putc (0x00,ouf); /* data length */
- putc (0x00,ouf);
- putc (0x00,ouf);
- putc (0x00,ouf);
-
- }
-
-
- /*\
- |*|----====< WriteckSize >====----
- |*|
- |*| write the header information on the .WAV file
- |*|
- \*/
- WriteckSize()
- {
- int n;
- char *s;
- long l;
-
- /* pad to a word boundary */
-
- PadByte = FALSE;
- if (((TotalSampleSize+44)&1)) {
- PadByte = TRUE;
- putc (lastsample,ouf);
- }
-
- printf ("\ntotal sample size = %ld\n",TotalSampleSize);
-
- /* close the output file */
-
- fclose (ouf);
-
- if ((ouf = fopen(TargetFile,"r+b")) == 0) {
- printf ("\acannot re-open the output file to install data size:\"%s\" Try Again!\n");
- DoExit (1);
- }
-
- /* write the data length of the sampled sound */
-
- fsetpos (ouf,&datapos);
- l = TotalSampleSize;
- for (n=0;n<4;n++) { putc (((char)(l & 0xff)),ouf); l = l >> 8; }
-
- /* write the riff length of the sampled sound */
-
- fsetpos (ouf,&riffpos);
- l = TotalSampleSize + 36;
- if (PadByte) l++;
- for (n=0;n<4;n++) { putc (((char)(l & 0xff)),ouf); l = l >> 8; }
-
- fclose (ouf);
- }
-
- /*\
- |*| end of PLAY
- \*/
-
-
-
-
-